package com.yystudy.rpc.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.dialect.Props;
import cn.hutool.setting.yaml.YamlUtil;

import java.util.Arrays;
import java.util.List;

/**
 * 配置工具类
 */
public class ConfigUtils {

    /**
     * 加载配置对象
     *
     * @param tClass 配置对象类型
     * @param prefix 配置文件中的前缀
     * @param <T>
     * @return 配置对象
     */
    public static <T> T loadConfig(Class<T> tClass, String prefix) {
        return loadConfig(tClass, prefix, "");
    }

    /**
     * 加载配置对象，支持区分环境
     *
     * @param tClass      配置对象类型
     * @param prefix      配置文件中的前缀
     * @param environment 环境（dev，test，prod）
     * @param <T>
     * @return 配置对象
     */
    public static <T> T loadConfig(Class<T> tClass, String prefix, String environment) {
        StringBuilder configFileBuilder = new StringBuilder("application");
        if (StrUtil.isNotBlank(environment)) {
            configFileBuilder.append("-").append(environment);
        }

        List<String> formats = Arrays.asList(".yml",".properties", ".yaml");
        for (String format : formats) {
            String path = configFileBuilder + format;
            if (!resourceExists(path)) continue;

            switch (format) {
                case ".properties":
                    // 使用 hutool 来读取properties配置文件生成对象
                    Props props = new Props(path);
                    // 将对象转为具体的自定义的配置对象
                    return props.toBean(tClass, prefix);
                case ".yml":
                case ".yaml":
                    // 使用 hutool 来读取yml配置文件生成对象
                    Dict dict = YamlUtil.loadByPath(path);
                    return BeanUtil.copyProperties(dict.getBean(prefix), tClass);
                default:
                    throw new RuntimeException("文件不合法");
            }
        }
        throw new RuntimeException("未找到配置文件");
    }


    /**
     * 判断资源是否存在
     *
     * @param path 资源路径
     * @return 是否存在
     */
    private static boolean resourceExists(String path) {
        // 使用当前线程的上下文类加载器
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        return classLoader.getResource(path) != null;
    }
}